/*
 * BSM6.0
 *
 * Copyright 2012-2013 (C) SINODATA CO., LTD. All Rights Reserved.
 */
package com.sinodata.bsm.center.web.action.event;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;

import com.sinodata.bsm.center.bean.Condition;
import com.sinodata.bsm.center.bean.EventBean;
import com.sinodata.bsm.center.bean.EventPropHisBean;
import com.sinodata.bsm.center.bean.NotifyHisBean;
import com.sinodata.bsm.center.bean.NotifyRuleBean;
import com.sinodata.bsm.center.bean.Page;
import com.sinodata.bsm.center.purview.FunctionConstants;
import com.sinodata.bsm.center.purview.UserFunctionValidate;
import com.sinodata.bsm.center.service.event.EventCorrelationService;
import com.sinodata.bsm.center.service.event.EventPropHisService;
import com.sinodata.bsm.center.service.event.EventRemarkService;
import com.sinodata.bsm.center.service.event.EventService;
import com.sinodata.bsm.center.service.notify.NotifyHisService;
import com.sinodata.bsm.center.service.notify.NotifyRuleService;
import com.sinodata.bsm.center.user.UserUtil;
import com.sinodata.bsm.center.util.web.Struts2Utils;
import com.sinodata.bsm.center.web.action.BaseAction;
import com.sinodata.bsm.common.constants.EventConstants;
import com.sinodata.bsm.common.constants.NotifyConstants;
import com.sinodata.bsm.common.vo.Event;
import com.sinodata.bsm.common.vo.EventCauses;
import com.sinodata.bsm.common.vo.EventCorrelation;
import com.sinodata.bsm.common.vo.EventRemark;
import com.sinodata.bsm.common.vo.NotifyReceiveRule;

/**
 * <p>
 * Description: 
 * </p>
 *
 * @author dongyushi
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-6-1 下午1:02:44          dongyushi        1.0         To create
 * </p>
 *
 * @since 
 * @see     
 */
public class EventViewAction extends BaseAction<Event> {

    /**
     * 
     */
    private static final long serialVersionUID = 8903749000991596L;
    @Autowired
    private EventService eventService;
    @Autowired
    private EventRemarkService eventRemarkService;
    @Autowired
    private EventPropHisService eventPropHisService;
    @Autowired
    private EventCorrelationService eventCorrelationService;
    @Autowired
    private NotifyHisService notifyHisService;

    @Autowired
    private NotifyRuleService notifyRuleService;

    public String view() throws Exception {
        Struts2Utils.getRequest().setAttribute("id", request.getParameter("id"));
        EventBean eventBean = eventService.findInformationById(Long.valueOf(request.getParameter("id")));
        eventBean.setLevelName(EventConstants.getLevelDesc(eventBean.getEvent().getLevel()));
        eventBean.setStatusName(EventConstants.getStatusDesc(eventBean.getEvent().getStatus()));
        eventBean.setLastOccurTime(eventBean.getLastOccurTime() == null ? "" : eventBean.getLastOccurTime());
        eventBean.setAckTime(eventBean.getAckTime() == null ? " " : eventBean.getAckTime());
        eventBean.setConfirmTime(eventBean.getConfirmTime() == null ? " " : eventBean.getConfirmTime());
        if (eventBean.getEvent().getConfirmType() != null && eventBean.getEvent().getConfirmType().equals(EventConstants.CONFIRM_TYPE_USER)) {
            eventBean.getEvent().setConfirmer(eventBean.getEvent().getConfirmer() == null ? " " : (UserUtil.getInstance().getUserById(eventBean.getEvent().getConfirmer()) == null ? eventBean.getEvent().getConfirmer() + "此用户已删除" : UserUtil.getInstance().getUserById(eventBean.getEvent().getConfirmer()).getFullName()));
        } else {
            eventBean.getEvent().setConfirmer(eventBean.getEvent().getConfirmer() == null ? " " : "系统");
        }
        eventBean.getEvent().setAckUser(eventBean.getEvent().getAckUser() == null ? " " : (UserUtil.getInstance().getUserById(eventBean.getEvent().getAckUser()) == null ? eventBean.getEvent().getAckUser() + "此用户已删除" : UserUtil.getInstance().getUserById(eventBean.getEvent().getAckUser()).getFullName()));
        //为了美观，标题名字不能超过100个字符
        if (eventBean.getEvent().getMsg().length() > 100) {
            eventBean.getEvent().setMsg(eventBean.getEvent().getMsg().substring(0, 100) + "...");
        }
        Struts2Utils.getRequest().setAttribute("eventBean", eventBean);
        Condition condition = new Condition();
        Map<String, String> map = new HashMap<String, String>();
        map.put("RES_ID", String.valueOf(eventBean.getEvent().getResId()));
        map.put("EVENT_TYPE_ID", String.valueOf(eventBean.getEvent().getEventTypeId()));
        //非过滤事件
        map.put("FILTER_EVENT_ID", null);
        condition.setWhere(map);
        List<EventBean> list = eventService.findEventByCondition(condition, "");
        Set<Map<String, String>> cause = new HashSet<Map<String, String>>();
        for (EventBean eb : list) {
            if (eb.getCauses() != null) {
                Map<String, String> map1 = new HashMap<String, String>();
                map1.put("id", eb.getCauses());
                map1.put("value", eb.getCauses());
                cause.add(map1);
            }
        }
        Struts2Utils.getRequest().setAttribute("causeList", cause);

        //初始化chartDate
        Struts2Utils.getRequest().setAttribute("chartData", chartData());
        List<EventPropHisBean> listEventPropHis = eventPropHisService.getEventPropHisByEventId(Long.valueOf(request.getParameter("id")));
        Struts2Utils.getRequest().setAttribute("listEventPropHis", listEventPropHis);
        //操作权限
        Struts2Utils.getRequest().setAttribute("handleAuth", UserFunctionValidate.resFunctionValidate(eventService.getEventById(Long.valueOf(request.getParameter("id"))).getResId(), FunctionConstants.HANDLE_EVENT));

        //事件通知标志
        Condition condition2 = new Condition();
        Map<String, String> map2 = new HashMap<String, String>();
        map2.put("event_id", request.getParameter("id"));
        condition2.setWhere(map2);
        List<NotifyHisBean> listNotify = notifyHisService.findByCondition(condition2, "");
        if (listNotify == null || listNotify.size() == 0) {
            Struts2Utils.getRequest().setAttribute("notifyflag", "false");
        } else {
            Struts2Utils.getRequest().setAttribute("notifyflag", "true");
        }
        //事件过滤标志
        Condition condition1 = new Condition();
        Map<String, String> map1 = new HashMap<String, String>();
        map1.put("CATALOG", String.valueOf(EventConstants.CATALOG_FAULTEVENT));
        map1.put("FILTER_EVENT_ID", request.getParameter("id"));
        condition1.setWhere(map1);
        List<EventBean> filterList = eventService.findEventByCondition(condition1, "");
        if (filterList == null || filterList.size() == 0) {
            Struts2Utils.getRequest().setAttribute("filterflag", "false");
        } else {
            Struts2Utils.getRequest().setAttribute("filterflag", "true");
        }
        //事件相关性
        List<EventCorrelation> listEventCorrelation = eventCorrelationService.findByMainEvent(Long.valueOf(request.getParameter("id")));
        if (listEventCorrelation == null || listEventCorrelation.size() == 0) {
            Struts2Utils.getRequest().setAttribute("relatedFlag", "false");
        } else {
            Struts2Utils.getRequest().setAttribute("relatedFlag", "true");
        }

        //事件通知规则
        List<NotifyRuleBean> notifyRuleBeans = notifyRuleService.findAllByRes(eventBean.getEvent().getResId());
        if (notifyRuleBeans == null || notifyRuleBeans.size() == 0) {
            Struts2Utils.getRequest().setAttribute("notifyRuleflag", "false");
        } else {
            Struts2Utils.getRequest().setAttribute("notifyRuleflag", "true");
        }
        return "common";
    }

    public String submitCause() {
        String id = request.getParameter("id");
        String cause = request.getParameter("cause");
        if (cause != null && !cause.equals("")) {
            EventCauses eventCauses = eventService.getEventCausesByEventId(Long.valueOf(id));
            eventCauses.setTitle(cause);
            Event event = eventService.getEventById(Long.valueOf(id));
            eventCauses.setEventId(event.getId());
            eventCauses.setEventTypeId(event.getEventTypeId());
            eventCauses.setResId(event.getResId());
            eventService.addEventCauses(eventCauses);
            renderText("true");
        } else {
            renderText("false");
        }
        return null;
    }

    /**
     * 通知页面列表
     * @return
     * @throws Exception
     */
    public String listNotify() throws Exception {
        String eventId = request.getParameter("eventId");
        Condition condition = new Condition();
        Map<String, String> map = new HashMap<String, String>();
        if (eventId != null && !eventId.equals("")) {
            map.put("event_id", eventId);
        }
        String format = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat simple = new SimpleDateFormat(format);
        condition.setWhere(map);
        List<NotifyHisBean> list = notifyHisService.findByCondition(condition, "");
        JSONObject json = new JSONObject();
        json.element("iTotalRecords", list.size());
        json.element("iTotalDisplayRecords", list.size());
        JSONArray array = new JSONArray();
        for (NotifyHisBean notifyHisBean : list) {
            JSONObject obj = new JSONObject();
            obj.element("user", UserUtil.getInstance().getUserById(notifyHisBean.getNotifyHis().getUser()).getFullName());
            obj.element("notifyMode", NotifyConstants.getModeDesc(notifyHisBean.getNotifyHis().getNotifyMode()));
            obj.element("time", simple.format(notifyHisBean.getNotifyHis().getTime()));
            obj.element("msg", notifyHisBean.getNotifyHis().getMsg());
            array.add(obj);
        }
        json.element("aaData", array);
        renderText(json.toString());
        return null;
    }

    /**
     * 通知规则列表
     * @return
     * @throws Exception
     */
    public String listNotifyRule() throws Exception {
        String eventId = request.getParameter("eventId");
        EventBean eventBean = eventService.findInformationById(Long.valueOf(eventId));
        List<NotifyRuleBean> notifyRuleBeans = notifyRuleService.findAllByRes(eventBean.getEvent().getResId());
        Set<String> set = new HashSet<String>();
        if (notifyRuleBeans != null) {
            for (NotifyRuleBean notifyRuleBean : notifyRuleBeans) {
                List<NotifyReceiveRule> notifyReceiveRules = notifyRuleBean.getNotifyReceiveRules();
                if (notifyReceiveRules != null) {
                    for (NotifyReceiveRule notifyReceiveRule : notifyReceiveRules) {
                        set.add(notifyReceiveRule.getUser());
                    }
                }
            }
        }
        JSONObject json = new JSONObject();
        json.element("iTotalRecords", set.size());
        json.element("iTotalDisplayRecords", set.size());
        JSONArray array = new JSONArray();
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String userId = it.next();
            JSONObject obj = new JSONObject();
            obj.element("user", UserUtil.getInstance().getUserById(userId).getFullName());
            obj.element("mobile", UserUtil.getInstance().getUserById(userId).getMobileTel());
            array.add(obj);
        }
        json.element("aaData", array);
        renderText(json.toString());
        return null;
    }

    /**
     * 过滤事件页面列表查询
     * @return
     * @throws Exception
     */
    public String listFilterByEventId() throws Exception {
        String eventId = request.getParameter("eventId");
        Condition condition = new Condition();
        Map<String, String> map = new HashMap<String, String>();
        map.put("CATALOG", String.valueOf(EventConstants.CATALOG_FAULTEVENT));
        map.put("FILTER_EVENT_ID", eventId);
        condition.setWhere(map);
        Page<EventBean> page = new Page<EventBean>();
        page.setPageNo(Integer.valueOf(request.getParameter("iDisplayStart")) / Integer.valueOf(request.getParameter("iDisplayLength")) + 1);
        page.setPageSize(Integer.valueOf(request.getParameter("iDisplayLength")));
        Page<EventBean> aaData = eventService.findEventByPage(page, condition, "");
        String format = "yyyy-MM-dd HH:mm";
        SimpleDateFormat simple = new SimpleDateFormat(format);
        JSONObject json = new JSONObject();
        json.element("iTotalRecords", page.getTotal());
        json.element("iTotalDisplayRecords", page.getTotal());
        JSONArray array = new JSONArray();
        for (EventBean eventBean : aaData.getRows()) {
            JSONObject obj = new JSONObject();
            obj.element("resName", eventBean.getResName());
            obj.element("eventTypeName", eventBean.getEventTypeName());
            obj.element("msg", eventBean.getEvent().getMsg());
            //事件级别
            obj.element("levelName", EventConstants.getLevelDesc(eventBean.getEvent().getLevel()));
            obj.element("occurTime", simple.format(eventBean.getEvent().getOccurTime()));
            obj.element("count", eventBean.getEvent().getCount() == null ? "" : eventBean.getEvent().getCount());
            obj.element("lastOccurTime", eventBean.getLastOccurTime() == null ? "" : eventBean.getLastOccurTime());
            array.add(obj);
        }
        json.element("aaData", array);
        renderText(json.toString());
        return null;
    }

    public String loadChartDate() {
        Struts2Utils.renderJson(chartData());
        return null;
    }

    private String chartData() {
        JSONObject json = new JSONObject();
        //chart
        JSONObject chart = new JSONObject();
        chart.element("caption", "产生原因统计");
        //chart.element("xaxisname", "原因类别");
        //chart.element("yaxisname", "原因个数");
        chart.element("numdivlines", "5");
        chart.element("useroundedges", "1");
        chart.element("plotborderdashed", "1");
        chart.element("plotborderdashgap", "1");
        chart.element("plotborderdashlen", "1");
        chart.element("showBorder", "0");

        //data
        JSONArray array = new JSONArray();
        Event event = eventService.getEventById(Long.valueOf(request.getParameter("id")));
        Condition condition = new Condition();
        Map<String, String> map = new HashMap<String, String>();
        map.put("RES_ID", String.valueOf(event.getResId()));
        map.put("EVENT_TYPE_ID", String.valueOf(event.getEventTypeId()));
        map.put("CATALOG", String.valueOf(EventConstants.CATALOG_FAULTEVENT));
        //非过滤事件
        map.put("FILTER_EVENT_ID", null);
        condition.setWhere(map);
        List<EventBean> list = eventService.findEventByCondition(condition, "");
        //获得原因及相应个数
        Map<String, Long> countMap = new HashMap<String, Long>();
        for (EventBean eventBean : list) {
            if (countMap.containsKey(eventBean.getCauses())) {
                Long count = countMap.get(eventBean.getCauses()) + 1;
                countMap.put(eventBean.getCauses(), count);
            } else {
                countMap.put(eventBean.getCauses(), 1l);
            }
        }

        List<Map.Entry<String, Long>> result = sortMapByValue(countMap);
        if (result.size() == 1) {
            chart.element("plotSpacePercent", "80");
        } else if (result.size() == 2 || result.size() == 3) {
            chart.element("plotSpacePercent", "50");
        }
        json.element("chart", chart);
        for (int j = 0; j < result.size(); j++) {
            JSONObject obj = new JSONObject();
            obj.element("label", result.get(j).getKey() == null ? "未知" : result.get(j).getKey());
            obj.element("color", getRandomColorCode());
            obj.element("value", result.get(j).getValue());
            array.add(obj);
            if (j > 4) {
                break;
            }
        }
        json.element("data", array);
        return json.toString();
    }

    public List<Map.Entry<String, Long>> sortMapByValue(Map<String, Long> map) {
        List<Map.Entry<String, Long>> result = new ArrayList<Map.Entry<String, Long>>(map.entrySet());
        Collections.sort(result, new Comparator<Map.Entry<String, Long>>() {
            @Override
            public int compare(Map.Entry<String, Long> obj2, Map.Entry<String, Long> obj1) {
                return obj1.getValue().intValue() - obj2.getValue().intValue();
            }
        });
        return result;
    }

    private String getRandomColorCode() {
        // 颜色代码位数  
        int colorLength = 6;
        // 颜色代码数组  
        char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < colorLength; i++) {
            sb.append(codeSequence[random.nextInt(16)]);
        }
        return sb.toString();
    }

    public String remarksList() throws Exception {
        String format = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat simple = new SimpleDateFormat(format);
        List<EventRemark> list = eventService.findEventRemarkByEventId(Long.valueOf(request.getParameter("eventId")));
        list = resultSort(list);
        JSONObject json = new JSONObject();
        json.element("iTotalRecords", list.size());
        json.element("iTotalDisplayRecords", list.size());
        JSONArray array = new JSONArray();
        for (EventRemark eventRemark : list) {
            JSONObject obj = new JSONObject();
            obj.element("time", simple.format(eventRemark.getTime()));
            obj.element("person", UserUtil.getInstance().getUserById(eventRemark.getUser()).getFullName());
            obj.element("remarks", eventRemark.getRemarks() == null ? "" : eventRemark.getRemarks());
            array.add(obj);
        }
        json.element("aaData", array);
        renderText(json.toString());
        return null;
    }

    private List<EventRemark> resultSort(List<EventRemark> sortList) {
        for (int i = 0; i < sortList.size(); i++) {
            for (int j = 0; j < sortList.size() - i - 1; j++) {
                if (sortList.get(j).getTime().compareTo(sortList.get(j + 1).getTime()) > 0) {
                    EventRemark tmp = sortList.get(j);
                    sortList.set(j, sortList.get(j + 1));
                    sortList.set(j + 1, tmp);
                }
            }
        }
        return sortList;
    }

    /**
     * 提交备注
     * @return
     * @throws Exception
     */
    public String submitRemark() throws Exception {
        String id = request.getParameter("id");
        String remark = new String(request.getParameter("remark").getBytes("ISO-8859-1"), "UTF-8");
        remark = remark.replace(" ", "----");
        remark = java.net.URLDecoder.decode(remark, "UTF-8");
        remark = remark.replace("----", "+");
        String userId = UserUtil.getInstance().getCurrentUserId();
        EventRemark eventRemark = new EventRemark();
        eventRemark.setEventId(Long.valueOf(id));
        eventRemark.setRemarks(remark);
        eventRemark.setUser(userId);
        eventRemark.setTime(new Date());
        eventRemarkService.add(eventRemark);
        renderText("true");
        return null;
    }

    @Override
    public Event getModel() {
        return null;
    }

    @Override
    public String list() throws Exception {
        return null;
    }

    @Override
    public String input() throws Exception {
        return null;
    }

    @Override
    public String save() throws Exception {
        return null;
    }

    @Override
    public String delete() throws Exception {
        return null;
    }

    @Override
    protected void prepareModel() throws Exception {

    }
}
